using System;
using System.Configuration;

namespace BoxBinary.AspectCache.Core.ConfigurationMappers
{
    /// <summary>
    /// Represents a collection of <see cref="CachePolicySpecification"/> objects.
    /// </summary>
    [Serializable, ConfigurationCollection(typeof (CachePolicySpecification))]
    public class CachePolicySpecificationCollection : ConfigurationElementCollection
    {
        /// <summary>
        /// Provides indexed access to the collection.
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public CachePolicySpecification this[int index]
        {
            get { return (CachePolicySpecification) BaseGet(index); }
            set
            {
                if (BaseGet(index) != null)
                    BaseRemoveAt(index);
                BaseAdd(index, value);
            }
        }

        /// <summary>
        /// Provides indexed access to the collection
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public new CachePolicySpecification this[string key]
        {
            get
            {
                var returnCat = (CachePolicySpecification) BaseGet(key.ToLower());
                if (returnCat == null)
                {
                    returnCat = (CachePolicySpecification) BaseGet("default");
                    if (returnCat == null)
                        return Configuration.GenerateDefaultCacheCategory();
                }
                return returnCat;
            }
        }

        protected override ConfigurationElement CreateNewElement()
        {
            return Configuration.GenerateDefaultCacheCategory();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((CachePolicySpecification) (element)).Key.ToLower();
        }

        /// <summary>
        /// Adds a <see cref="CachePolicySpecification"/> to the collection.
        /// </summary>
        /// <param name="element"></param>
        public void Add(CachePolicySpecification element)
        {
            var existing = (CachePolicySpecification) BaseGet(element.Key.ToLower());
            if (existing != null)
            {
                // Override existing member rather than adding a duplicate
                existing.Footprint = element.Footprint;
            }
            else
                BaseAdd(element);
        }

        /// <summary>
        /// Removes the <see cref="CachePolicySpecification"/> from the collection with the given key.
        /// </summary>
        /// <param name="key"></param>
        public void Remove(int key)
        {
            BaseRemove(key);
        }

        /// <summary>
        /// Clears the collection.
        /// </summary>
        public void Clear()
        {
            BaseClear();
        }
    }
}